package com.ysd.twocrm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ysd.twocrm.entity.*;
import com.ysd.twocrm.mapper.LeavetableMapper;
import com.ysd.twocrm.mapper.UserChecksMapper;
import com.ysd.twocrm.mapper.UserRolesMapper;
import com.ysd.twocrm.mapper.WageMapper;
import com.ysd.twocrm.service.MailService;
import com.ysd.twocrm.service.WageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class WageServiceImpl implements WageService {
    @Autowired
    private WageMapper wageMapper;
    @Autowired
    private UserChecksMapper userChecksMapper;
    @Autowired
    private LeavetableMapper leavetableMapper;

    @Autowired
    private MailService mailService;
    @Autowired
    private UserRolesMapper userRolesMapper;


    /*
     * @Description 获取上月的年月
     * @param
     * @return java.lang.String
     * @author liusupeng
     * @date 2020/6/5 17:05
     */

    public  String lastmonth(){

        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM");

        Calendar c=Calendar.getInstance();
        c.set( c.get(Calendar.YEAR),c.get(Calendar.MONTH),0);
       // System.out.println("上个月：>======================"+sdf.format(c.getTime()));
        return sdf.format(c.getTime());

    }



    /*
     * @Description  根据毫秒来获取分钟
     * @param mss
     * @return double
     * @author liusupeng
     * @date 2020/5/22 10:03
     */
    public  double timeGetTimeSum(long mss){



        return (mss/1000)/60;
    }
    /*
     * @Description  获取当前月份有多少天
     * @param
     * @return int
     * @author liusupeng
     * @date 2020/5/22 10:01
     */
    public  int maxdayInmonth(){

        Calendar calendarday=Calendar.getInstance();
        int year=calendarday.get(Calendar.YEAR);//当前年
        int month=calendarday.get(Calendar.MONTH);//拿到上个月的
        calendarday.set(year,month,0);//设置年月
        int day = calendarday.get(Calendar.DAY_OF_MONTH);//获取当前月份有多少天
        return day;

    }
    /*
     * @Description 判断当前时间是周几
     * @param checkin
     * @return int
     * @author liusupeng
     * @date 2020/5/22 10:40
     */
    int getweek(Date checkin) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(checkin);
        return calendar.get(Calendar.DAY_OF_WEEK) - 1;//判断当前遍历的打卡时间是周几,这里-1是为了对应周几，必须加。
    }
    /*
     * @Description  获取到当前年份还有月份，获取到当前月份有多少天（调用的方法）。
     * 然后获取当前年份月份
     * 然后通过字符串拼接的形式先拼接下日期，然后存到类型为date的集合里
     * 然后开始判断参数里的集合和这个全部日期的集合是否一致，不一致的就是旷工的日子
     * 接下来返回dete集合
     * @param datecheckinlist:已经打卡的集合
     * @return List<Date>
     * @author liusupeng
     * @date 2020/5/22 10:00
     */
    public List<Date> timeday(List<Date> datecheckinlist) throws ParseException {

        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        int day = maxdayInmonth();//获取当前月份多少天
        Calendar calendarday=Calendar.getInstance();
        int year=calendarday.get(Calendar.YEAR);//当前年
        int month=calendarday.get(Calendar.MONTH);//拿到上月的
        List<Date> datelist=new ArrayList<Date>();
        for(int j=1;j<=day;j++){
            Date date=new Date();
            String formart=year+"-"+month+"-"+j;
            datelist.add(sdf.parse(formart));
        }
        //拿到没打卡的时间
        for (int i = 0; i < datelist.size(); i++) {
            for (int j = 0; j < datecheckinlist.size(); j++) {
                if (datelist.get(i).getTime() == datecheckinlist.get(j).getTime()) {
                    datelist.remove(i);
                }
            }
        }

        return datelist;
    }
    //计算工资
    public Object testwage(String name,Integer userId) throws ParseException {


        Double basepay = 3500.00;//基本工资
        Integer presenteveryday = 200;//全勤
        Integer jobsubsidies = 100;//岗位补贴
        double netparybasepay=0.00;//实发基本工资
        double overtime=0.00;//加班
        double breaktherule=0.0;//违纪扣除
        Integer belatesum = 0;//迟到次数
        Integer leaveearlysum = 0;//早退次数
        Integer kuanggongsum=0;//旷工次数
        Integer performance=0;//业绩抽成钱
        int day = maxdayInmonth();//获取当前月份有多少天
        double minute = basepay / day / 8 / 60;//一分钟多少钱
        //    System.out.println(minute);
        double netpayroll = 0.0;//实发工资
        List<Date> datecheckinlist = new ArrayList<>();//存储打卡时间

        //查看打卡
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM");
        //取到请假的数据
        QueryWrapper<Leavetable> leavetableQueryWrapper=new QueryWrapper<Leavetable>();
        leavetableQueryWrapper.eq("lstatus",0).eq("userId",userId).eq("lname",name).likeRight("lsubmit",lastmonth());
        List<Leavetable> leavetables = leavetableMapper.selectList(leavetableQueryWrapper);
         System.out.println(leavetables.size()+">===当月请假次数");
        QueryWrapper<Userchecks> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userCheckName", name).eq("userId",userId).likeRight("userCheckInTime", lastmonth());
        List<Userchecks> userchecks = userChecksMapper.selectList(queryWrapper);
        System.out.println(userchecks.size()+">===========");
        for (int i = 0; i < userchecks.size(); i++) {
            datecheckinlist.add(sdf1.parse(sdf1.format(userchecks.get(i).getUserCheckInTime())));//转换成Yyyy-mm-dd了类型
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(userchecks.get(i).getUserCheckInTime());
            int week = getweek(calendar.getTime());//判断当前遍历的打卡时间是周几,这里-1是为了对应周几，必须加。

            //进行上班操作
            Date userCheckInTime = userchecks.get(i).getUserCheckInTime();//打卡时间
            Date userCheckOutTime = userchecks.get(i).getUserCheckOutTime();//下班打卡时间

            Calendar c = Calendar.getInstance();
            c.setTime(userCheckInTime);

            String format = sdf1.format(c.getTime());//当前打卡的年月日
            String checkin = format + " 08:00:00";//打卡上班时间设置8点
            String checkout = format + " 17:00:00";//打卡下班时间设置17点
            Date formatparsecheckin = sdf.parse(checkin);//上班打卡时间设置8点,转换成date类型
            Date formatparsecheckout = sdf.parse(checkout);//下班打卡时间设置下午5点,转换成date类型
            //如果下班为空
            if(userCheckOutTime==null){
                userCheckOutTime=sdf.parse(checkout);//如果他没有打卡就默认下午5点打卡
            }
            // 周日是0 周一是1 周二是2 以此类推
            if (week == 1 || week == 2 || week == 3 || week == 4 || week == 5) {
                if (userCheckInTime.getTime() < formatparsecheckin.getTime()) {
                    //如果打卡时间在8点以前，就把当前的打卡时间设置成8点整
                    userCheckInTime = formatparsecheckin;
                    //  System.out.println("打卡早了，设置计算时间的话为打卡8点");
                } else {
                    //System.out.println("迟到了开始扣钱");
                    //再去查当前这个在请假表的请假结束时间表是否存在
                    for(int s=0;s<leavetables.size();s++){

                        if(sdf1.format(userCheckInTime).equals(sdf1.format(leavetables.get(s).getLsubmit()))){
                            //如果迟到并且当天日期在经过条件筛选的请假表里存在过在判断
                            //这里使用大于号来判断，
                            //假如请假结束时间是8：20 但是我8:30去打卡了，那这样的话就算迟到。
                            if(userCheckInTime.getTime()>leavetables.get(s).getEndtime().getTime()){

                                break;//如果迟到了就跳出这个循环就行，在外层还有处理
                            }else{
                                //这是虽然迟到，但是已经请过假了，所以不需要扣钱，因为外层循环扣了，所以这里加过来
                                netpayroll += 50;
                                breaktherule-=50;//在变量违纪扣除+，用于添加数据用
                                belatesum--;

                            }
                        }

                    }
                    netpayroll -= 50;//扣50
                    breaktherule+=50;//在变量违纪扣除+，用于添加数据用
                    belatesum++;


                }
                //进行下班操作
                //首先需要先判断是否早退
                if (userCheckOutTime.getTime() < formatparsecheckout.getTime()) {

                    //   System.out.println("早退");
                    //再去查当前这个在请假表的请假开始时间表是否存在
                    for(int s=0;s<leavetables.size();s++){
                        //  System.out.println(123);
                        // System.out.println(sdf1.format(userCheckInTime));
                        //  System.out.println(sdf1.format(leavetables.get(s).getLsubmit()));
                        if(sdf1.format(userCheckInTime).equals(sdf1.format(leavetables.get(s).getLsubmit()))){
                            //如果早退并且当天日期在经过条件筛选的请假表里存在过在判断
                            //这里使用大于号来判断，
                            //假如请假开始时间是8：20 但是我8:10去打卡下班了，那这样的话就算早退。
                            if(userCheckOutTime.getTime()<leavetables.get(s).getBegintime().getTime()){
                                System.out.println("在请假表里早退");
                                break;//如果早退了就跳出这个循环就行，在外层还有处理
                            }else{
                                //这是虽然早退，但是已经请过假了，所以不需要扣钱，因为外层循环扣了，所以这里加过来
                                netpayroll += 100;//不需要扣钱所以加一下
                                breaktherule-=100;//在变量违纪扣除+，用于添加数据用
                                leaveearlysum--;
                            }
                        }

                    }
                    netpayroll -= 100;//扣100
                    breaktherule+=100;//在变量违纪扣除+，用于添加数据用
                    leaveearlysum++;

                } else {
                    long timesum = userCheckOutTime.getTime() - formatparsecheckout.getTime();//拿到加班的时间
                    double v = timeGetTimeSum(timesum);//加班的时间（分钟）

                    double jiaban = minute * 1.5 * v;
                    overtime+=minute * 1.5 * v;//加班变量＋下（用于添加数据用）

                    netpayroll += jiaban;//将加班的工资发进去
                    userCheckOutTime = formatparsecheckout;//一旦加班了就把打卡下班时间设置成下午5点来计算

                    //   System.out.println("加班");
                }



                //周一到周五 拿基本工资
                long everyday = userCheckOutTime.getTime() - userCheckInTime.getTime();
                double shijiminue = timeGetTimeSum(everyday) - 60;//每天早8晚5的分钟没有午休
                //  System.out.println("每天早8晚五的分钟:"+shijiminue+"时间："+userCheckInTime);
                netpayroll += shijiminue * minute;
                netparybasepay+=shijiminue * minute;//实发基本工资(用于添加数据)



            } else {
                //开始加班咯
                if (userCheckInTime.getTime() < formatparsecheckin.getTime()) {
                    //如果打卡时间在8点以前，就把当前的打卡时间设置成8点整
                    userCheckInTime = formatparsecheckin;
                    //  System.out.println("开始："+userCheckInTime+"结束"+userCheckOutTime);
                    long everyday = userCheckOutTime.getTime() - userCheckInTime.getTime();
                    double shijiminue = timeGetTimeSum(everyday);//星期天上班（必须8点）下班差距的时间没有午休
                    netpayroll += minute * 2 * shijiminue;
                    overtime+=minute * 2 * shijiminue;//加班变量＋下（用于添加数据用）

                    //  System.out.println("打卡早了，设置计算时间的话为打卡8点");
                } else {
                    //超过8点

                    long everyday = userCheckOutTime.getTime() - userCheckInTime.getTime();
                    double shijiminue = timeGetTimeSum(everyday);//星期天上班下班差距的时间
                    netpayroll += minute * 2 * shijiminue;
                    overtime+=minute * 2 * shijiminue;//加班变量＋下（用于添加数据用）

                }
            }


        }

        List<Date> timeday = timeday(datecheckinlist);//调用方法


        for (int i = 0; i < timeday.size(); i++) {

            //拿到旷工的日子
            int week=getweek(timeday.get(i));
            //  System.out.println(sdf1.format(timeday.get(i))+"周几："+week);
            if (week == 1 || week == 2 || week == 3 || week == 4 || week == 5) {
                //在判断是否请假。没有请假就旷工
            if(leavetables.size()>0){
                for(int j=0;j<leavetables.size();j++){
                    System.out.println(timeday.get(i)+">====旷工");
                    System.out.println(leavetables.get(j)+">====请假");
                    if(sdf1.format(timeday.get(i)).equals(sdf1.format(leavetables.get(j).getLsubmit()))){
                        //如果这些旷工的日子在假期表里存在，那么就代表当天没有旷工，是请假了。
                        //请假了所以就要把旷工
                        System.out.println("我请假了");

                    }else{

                        //旷工了
                        presenteveryday=0;//全勤设置0
                        netpayroll-=200;//实发工资-200
                        breaktherule+=200;//违纪扣除
                        kuanggongsum++;//旷工次数++
                    }
                }
            }else{
                //如果请假表里不存在数据就旷工
                //旷工了
                presenteveryday=0;
                netpayroll-=200;
                breaktherule+=200;//用于添加数据用
                kuanggongsum++;
            }

            }
        }
        String deductmoneyremark="";
        if(belatesum!=0 || leaveearlysum!=0 || kuanggongsum !=0){
            if(belatesum!=0){
                System.out.println("测试迟到"+leaveearlysum+kuanggongsum);
                deductmoneyremark+=" 迟到次数:"+belatesum;
            } if(leaveearlysum!=0){
                System.out.println("测试早退"+leaveearlysum+kuanggongsum);
                deductmoneyremark+=" 早退次数:"+leaveearlysum;
            } if(kuanggongsum!=0){
                System.out.println("测试旷工"+leaveearlysum+kuanggongsum);
                deductmoneyremark+=" 旷工次数:"+kuanggongsum;
            }
        }
        if(netpayroll<0){
            netpayroll=0.0;//如果基本工资是负数就设置成0
        }
        System.out.println(deductmoneyremark);
        //获取上个月咨询师的业绩，有一个就加630 抽成10个点
        List<UserRoles> allByStudentLogs = userRolesMapper.findAllByStudentLogs(lastmonth());
   for(int i=0;i<allByStudentLogs.size();i++){
       if(allByStudentLogs.get(i).getUserId().equals(userId)){
           performance+=630;
       }
   }

        //将工资的信息存到工资实体里
        Wage wage=new Wage(0,basepay.intValue(),netparybasepay,jobsubsidies,overtime,breaktherule,netpayroll+jobsubsidies+presenteveryday+performance,deductmoneyremark,presenteveryday,userId,new Date(),performance);
        return wage;
    }


    /*
     * @Description 添加工资
     * @param wage
     * @return java.lang.Integer
     * @author liusupeng
     * @date 2020/5/22 18:33
     */
    @Override
    public Integer insertwage(String name,String emails,Integer userId )   {
        try {
            Wage testwage = (Wage) testwage(name,userId);
            int insert = wageMapper.insert(testwage);
            if(insert>0){
                //执行发送邮件
                EmailUtils emailUtils=new EmailUtils();
                emailUtils.setTitle("工资条");
                emailUtils.setTo(emails);

                emailUtils.setContent(name+"同志,您好，"+lastmonth()+"月的工资已打印出来。您的工资如下:<p>基本工资:"+testwage.getBasepay()+"</p><p>实发基本工资:"+testwage.getNetparybasepay()+"</p><p>岗位津贴:"+testwage.getJobsubsidies()+"</p><p>加班补贴:"+testwage.getOvertime()+"</p><p>违纪扣除:"+testwage.getBreaktherule()+"</p><p>实发工资:"+testwage.getNetpayroll()+"</p><p>扣除原因:"+testwage.getDeductmoneyremark()+"</p><p>全勤奖:"+testwage.getPresenteveryday()+"</p><p>您的提成奖::"+testwage.getExit1()+"</p>");
                mailService.sendMail(emailUtils);
                return 1;
            }else{
                return 0;
            }

        } catch (ParseException e) {
            e.printStackTrace();
            return 0;
        }




    }
}
